
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>PDF Preview</title>
</head>
<body>
<div id="pdf-container">
  <button onclick="initui()">点我</button>
  <embed id="pdf-embed" type="application/pdf" width="100%" height="600px" />
</div>
<script>        async function fetchBase64Pdf() {
  const response = await fetch('http://localhost:8081/pdf03/test01');
  const base64Pdf = await response.text();
  return base64Pdf;
}

async function displayPdf(base64Pdf) {
  const pdfUrl = `data:application/pdf;base64,${base64Pdf}`;
  document.getElementById('pdf-embed').src = pdfUrl;
}

async function init() {
  const base64Pdf = await fetchBase64Pdf();
  if (base64Pdf) {
    await displayPdf(base64Pdf);
  }
}
const CHUNK_SIZE = 1024 * 1024; // 1MB
async function fetchPdfChunks() {
  const url = 'http://localhost:8081/pdf03/test01/chunk';
  let start = 0;
  let end = CHUNK_SIZE - 1;
  let totalSize = 0;
  let chunks = [];

  while (true) {
    console.log(`Fetching chunk from ${start} to ${end}`);
    const response = await fetch(`${url}?start=${start}&end=${end}`,{
      headers: {
        'Accept': 'application/pdf'
      }
    });

    if (response.status === 206) {
      console.log("206...")
      const blobChunk = await response.blob();
      console.log(`Received chunk of size ${blobChunk.size} bytes`);
      chunks.push(blobChunk);
      const contentRange = response.headers.get('Content-Range');
      if (contentRange) {
        const rangeParts = contentRange.split('/');
        totalSize = parseInt(rangeParts[1]);

        start = end + 1;
        end = Math.min(start + CHUNK_SIZE - 1, totalSize - 1);
        if (start >= totalSize){
          break;
        }
      } else {
        console.log("没进入contentRange...")
        console.error('Content-Range header is missing in the response');
        break;
      }
    } else if (response.status === 200) {
      console.log("200...")
      const blobChunk = await response.blob();
      console.log(`Received final chunk of size ${blobChunk.size} bytes`);
      chunks.push(blobChunk);
      break;
    } else {
      console.log("error...")
      console.error('Failed to fetch PDF chunk',response);
      break;
    }
  }
  // 合并所有分块
  console.log(chunks)
  const completeBlob = new Blob(chunks, { type: 'application/pdf' });
  const pdfUrl = URL.createObjectURL(completeBlob);
  document.getElementById('pdf-embed').src = pdfUrl;
  //console.log(chunks)
  //console.log(completeBlob)
  // 保存拼接后的 PDF 数据到文件
  // 保存拼接后的 PDF 数据到文件
  // 检查最终文件大小
  console.log(`Total chunks received: ${chunks.length}`);
  console.log(`Complete Blob size: ${completeBlob.size} bytes`);
  console.log(`Expected total size: ${totalSize} bytes`);

  try {
    const link = document.createElement('a');
    link.href = pdfUrl;
    link.download = 'output.pdf';
    link.click();
  } catch (error) {
    console.error('Failed to create Blob from chunks:', error);
  }
}
function cleanBase64(base64String) {
  // 移除空格和换行符
  base64String = base64String.replace(/[\s\n\r]+/g, '');

  // 确保字符串长度是 4 的倍数
  const paddingLength = (4 - (base64String.length % 4)) % 4;
  return base64String + '='.repeat(paddingLength);
}
function base64ToBlob(base64String, contentType = 'application/pdf') {
  // 清理输入字符串，移除空格和换行符
  //console.log("原始base64字符串"+base64String)
  const cleanedBase64String = base64String.replace(/\s+/g, '');

  // 确保字符串长度是 4 的倍数
  const paddedBase64String = padBase64(cleanedBase64String);
  if (!isBase64(paddedBase64String)) {
    console.log("验证失败。。")
    throw new Error('Invalid Base64 string');
  }
  // 解码 Base64 字符串
  const binaryString = atob(paddedBase64String);

  console.log("base64ToBlob报错。。。")
  // 将解码后的字符串转换为字节数组
  const bytes = new Uint8Array(binaryString.length);
  for (let i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  // 创建 Blob 对象
  const blob = new Blob([bytes], { type: contentType });

  return blob;
}
function padBase64(base64String) {
  const paddingLength = (4 - (base64String.length % 4)) % 4;
  return base64String + '='.repeat(paddingLength);
}
function isBase64(str) {
  try {
    return btoa(atob(str)) === str;
  } catch (err) {
    return false;
  }
}
// function decodeBase64InChunks(base64String, chunkSize = 1024 * 1024) {
//   const chunks = [];
//   for (let i = 0; i < base64String.length; i += chunkSize) {
//     const chunk = base64String.slice(i, i + chunkSize);
//     chunks.push(atob(chunk));
//   }
//
//   // 合并所有解码后的块
//   const combinedBinaryString = chunks.join('');
//
//   // 将解码后的字符串转换为字节数组
//   const bytes = new Uint8Array(combinedBinaryString.length);
//   for (let i = 0; i < combinedBinaryString.length; i++) {
//     bytes[i] = combinedBinaryString.charCodeAt(i);
//   }
//
//   return bytes;
// }
function initui(){
  //init();
  fetchPdfChunks()
}

</script>
</body>
</html>